#!/usr/bin/env bash

# Utility script to check the game sanity
# As of now, this script does not repair files.
#
# Usage: ./check_integrity.sh FILENAME quick
#    FILENAME : Checksum file e.g. "pkg_version" of the game or voiceover pack
#    "quick"  : Skips md5 checks for more speed but is less reliable

set -e

# ======== Functions

fatal() {
	echo
	for arg in "$@"; do
		echo "  *  $arg" >&2
	done
	echo

	exit 1
}

bad_filepaths=()
on_file_mismatch() {
	# 1 = Error Msg, 2 = Filepath
	echo "$1 : $2"
	bad_filepaths+=("$2")
}

if [[ $(uname) == "Darwin" || $(uname) == *"BSD" ]]; then
	STATFLAGS="-f %z"
	md5sum() {
		md5 -q $@
	}
else
	STATFLAGS="-c %s"
fi


# ======== Evaluated variables

MASTER_FILE="$1"
CHECK_MD5=1

[ ! -e "$MASTER_FILE" ] && fatal \
	"Checksum file $MASTER_FILE not found."

if [ "$2" == "quick" ]; then
	CHECK_MD5=0
	echo "--- Mode: Quick file size checking (fast, less reliable)"
else
	echo "--- Mode: Detailed md5 checking (slow, most reliable)"
fi

# This is faster than running "jq" on each line
# outputs a string in form of "Direcotry/File.ext|abc123|10001"
per_line_data=$(jq -r "[.remoteName, .md5, .fileSize] | join(\"|\")" "$MASTER_FILE")

i=0
while IFS='|' read -r filepath checksum filesize; do
	i=$((i + 1))

	#echo "$test $filepath $checksum $filesize"
	if [ ! -e "$filepath" ]; then
		on_file_mismatch "Missing" "$filepath"
		continue
	fi

	size=$(stat $STATFLAGS "$filepath")
	if [ "$size" -ne "$filesize" ]; then
		on_file_mismatch "Size mismatch: $size != $filesize" "$filepath"
		continue
	fi
	if [ "$CHECK_MD5" -eq 1 ]; then
		sum=($(md5sum "$filepath"))
		if [ "$sum" != "$checksum" ]; then
			on_file_mismatch "Checksum error: $sum != $checksum" "$filepath"
			continue
		fi
	fi

	# Log file names every now and then
	if [ $((i % 300)) == 0 ]; then
		echo "--- Progress: File N°${i}"
	fi
done <<< "$per_line_data"

echo ""
echo "==> List of files that do not correspond to the original game"
echo "    Certain files might be missing or modified due to patching"

for filepath in "${bad_filepaths[@]}"; do	
	echo -e "\t$filepath"
done

echo "==> END"

exit 0
